﻿using System;
using System.Configuration;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Xml;

namespace Se.Framework.Logging
{
    internal class Log4NetLogger : ISourceableLogger
    {
        /*
         * Levels:
            ALL
            DEBUG
            INFO
            WARN
            ERROR
            FATAL
            OFF
         * <add key="log4net.Config" value="log4net.config" />
         * <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
         */

        private static readonly log4net.ILog log = log4net.LogManager.GetLogger("Talent Wall 2");

        public Log4NetLogger()
        {
            if (!LoadFromFile())
                log4net.Config.XmlConfigurator.Configure();
        }

        private bool LoadFromFile()
        {
            if (ConfigurationManager.AppSettings["log4net.config"] != null)
            {
                try
                {
                    string path = Assembly.GetExecutingAssembly().CodeBase.Remove(0, 8).Replace(Path.AltDirectorySeparatorChar, Path.DirectorySeparatorChar);
                    path = path.Substring(0, path.LastIndexOf(Path.DirectorySeparatorChar));
                    XmlDocument doc = new XmlDocument();
                    doc.Load(Path.Combine(path, ConfigurationManager.AppSettings["log4net.config"]));
                    log4net.Config.XmlConfigurator.Configure(doc.DocumentElement);
                    return true;
                }
                catch (Exception ex)
                {
                    System.Diagnostics.Trace.TraceError("Logger Configuration error: {0}", ex);
                }
            }

            return false;
        }

        public void Error(string message, params object[] parameters)
        {
            log.Error(ResolveMessage(message, parameters));
        }

        public void Error(Exception ex, string message, params object[] parameters)
        {
            log.Error(ResolveMessage(message, parameters), ex);
        }

        public void Information(string message, params object[] parameters)
        {
            log.Info(ResolveMessage(message, parameters));
        }

        public void Warning(string message, params object[] parameters)
        {
            log.Warn(ResolveMessage(message, parameters));
        }

        public void Debug(string message, params object[] parameters)
        {
            log.Debug(ResolveMessage(message, parameters));
        }

        public void Error(ILogSource source, Exception ex, string message, params object[] parameters)
        {
            source.GetLogger().Error(ResolveMessage(message, parameters), ex);
        }

        public void Error(ILogSource source, string message, params object[] parameters)
        {
            source.GetLogger().Error(ResolveMessage(message, parameters));
        }

        public void Warning(ILogSource source, string message, params object[] parameters)
        {
            source.GetLogger().Warn(ResolveMessage(message, parameters));
        }

        public void Information(ILogSource source, string message, params object[] parameters)
        {
            source.GetLogger().Info(ResolveMessage(message, parameters));
        }

        public void Debug(ILogSource source, string message, params object[] parameters)
        {
            source.GetLogger().Debug(ResolveMessage(message, parameters));
        }

        private object ResolveMessage(string message, params object[] parameters)
        {
            return parameters == null ? message : string.Format(message, parameters);
        }
    }
}
